﻿using Furion;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

namespace MOKA.TPM.Utility
{ 
    public class LogHelper
    {
        private static Dictionary<long, long> lockDic = new Dictionary<long, long>();  

        //在程序根目录下创建日志目录
        public static string path = App.WebHostEnvironment != null ? App.WebHostEnvironment.ContentRootPath + "/Logs" : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, (AppDomain.CurrentDomain.RelativeSearchPath ?? string.Empty).Split(';').First(), "Logs");

        /// <summary>
        /// 错误日志写入
        /// </summary>
        /// <param name="type">写入日志的类类型</param>
        /// <param name="msg">错误信息</param>
        /// <param name="remark">错误备注</param>
        public static void Write(string methodName, string message, string remark)
        {
            WriteLog(methodName, message, remark);
        }

        /// <summary>
        /// 错误日志写入
        /// </summary>
        /// <param name="type">写入日志的类类型</param>
        /// <param name="msg">错误信息</param>
        public static void Write(string methodName, string message)
        {
            WriteLog(methodName, message, "");
        }

        /// <summary>
        /// 错误日志写入
        /// </summary>
        /// <param name="type">写入日志的类类型</param>
        /// <param name="msg">错误信息</param>
        public static void Write(Exception ex)
        {
            WriteLog(ex.TargetSite.DeclaringType.FullName + "." + ex.TargetSite.Name, ex.GetType().ToString() + "：" + ex.Message + "——堆栈信息：" + ex.StackTrace, "");
        }

        /// <summary>
        /// 实际日志写入
        /// </summary>
        /// <param name="methodName">写入日志的类名</param>
        /// <param name="message">日志信息</param>
        /// <param name="remark">备注</param>
        protected static void WriteLog(string methodName, string message, string remark)
        {
            if (!string.IsNullOrEmpty(path))
            {
                if (!Directory.Exists(path))//如果日志目录不存在就创建
                {
                    Directory.CreateDirectory(path);
                }

                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");//获取当前系统时间
                string filename = System.IO.Path.Combine(path, DateTime.Now.ToString("yyyy-MM-dd") + ".log");//用日期对日志文件命名


                try
                {
                    //向日志文件写入内容
                    StringBuilder stringBuilder = new StringBuilder(time);
                    stringBuilder.Append("   ");
                    stringBuilder.AppendLine(methodName);
                    stringBuilder.Append("ErrorMessage:  ");
                    stringBuilder.AppendLine(message);
                    stringBuilder.Append("Remark:  ");
                    stringBuilder.AppendLine(remark);
                    stringBuilder.AppendLine();
                    stringBuilder.AppendLine();

                    using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite, 8, System.IO.FileOptions.Asynchronous))
                    { 
                        Byte[] dataArray = System.Text.Encoding.Default.GetBytes(stringBuilder.ToString());
                        bool flag = true;
                        long slen = dataArray.Length;
                        long len = 0;
                        while (flag)
                        {
                            try
                            {
                                if (len >= fs.Length)
                                {
                                    fs.Lock(len, slen);
                                    lockDic[len] = slen;
                                    flag = false;
                                }
                                else
                                {
                                    len = fs.Length;
                                }
                            }
                            catch (Exception ex)
                            {
                                while (!lockDic.ContainsKey(len))
                                {
                                    len += lockDic[len];
                                }
                            }
                        }
                        fs.Seek(len, System.IO.SeekOrigin.Begin);
                        fs.Write(dataArray, 0, dataArray.Length);
                        fs.Close();
                    }  
                }
                catch { }
            }
        }
    }
}
